package com.tencent.shadow.sample.host.http;

import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.meichis.mcsappframework.BaseApplication;
import com.meichis.mcsappframework.utils.GzipTool;
import com.meichis.mcsappframework.utils.SharePreferenceUtil;
import com.meichis.mcsappframework.utils.Tools;
import com.tencent.shadow.sample.host.BuildConfig;
import com.tencent.shadow.sample.host.MCApplication;
import com.tencent.shadow.sample.host.common.APIWEBSERVICE;
import com.tencent.shadow.sample.host.http.RetrofitUtil.CallManager;
import com.tencent.shadow.sample.host.http.RetrofitUtil.RxSchedulersHelper;
import com.tencent.shadow.sample.host.model.WSIRequestPack;
import com.tencent.shadow.sample.host.model.WSIResultPack;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.UUID;

import io.reactivex.Observable;
import okhttp3.Interceptor;
import okhttp3.Request;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by chenhaifei on 2016/3/22.
 */

/**
 * Created by chenhaifei on 2016/3/22.
 */
public class HttpRequestImpl<S> extends CallManager {
    private static final String TAG = "HttpRequestImpl";

    private volatile static HttpRequestImpl httpRequest;

    public static HttpRequestImpl getInstance() {
        if (httpRequest == null) {
            synchronized (HttpRequestImpl.class) {
                if (httpRequest == null) {
                    httpRequest = new HttpRequestImpl();
                }
            }
        }
        return httpRequest;
    }


    public synchronized <S> void sendRequest(IWebServiceCallback callback, Class<S> serviceClazz, int sequence, String ServiceCode, String ParamsStr) {
        sendRequest(callback, serviceClazz, sequence, ServiceCode, ParamsStr, false, 0);
    }

    public synchronized <S> void sendRequest(IWebServiceCallback callback, Class<S> serviceClazz, int sequence, String ServiceCode, String ParamsStr, boolean EncryptFlag) {
        sendRequest(callback, serviceClazz, sequence, ServiceCode, ParamsStr, EncryptFlag, 0);
    }

    public synchronized <S> void sendRequest(IWebServiceCallback callback, Class<S> serviceClazz, int sequence, String ServiceCode, String ParamsStr, boolean EncryptFlag, int time) {
        if (!Tools.isConnected(MCApplication.getContext())) {
            callback.onFailure(  -1,-200, "网络未连接，请检查网络！");
            return;
        }
        S service = createService(serviceClazz, BuildConfig.REMOTE_MCSWSIAPI, GsonConverterFactory.create());
        WSIRequestPack requestPack = new WSIRequestPack();
        requestPack.setMessageId(UUID.randomUUID().toString());
        SharePreferenceUtil util = SharePreferenceUtil.getInstance();
        String AuthKey = (String) util.getCacheValue(SharePreferenceUtil.PREFERENCES_AUTHKEY);
        //图片上传时，暂不压缩
        if (ParamsStr.length() >= 2048 && !ParamsStr.contains("picData")) {
            requestPack.setCompressFlag("Y");
            ParamsStr = GzipTool.encryptGZIP(ParamsStr);
        }
        requestPack.setParams(ParamsStr);
        requestPack.setDeviceCode(Tools.getDeviceId(BaseApplication.getContext()));
        if (BuildConfig.DEBUG) {
            Log.v(TAG, "ServiceCode" + ServiceCode + "\tAuthKey = " + AuthKey + "\t||Request:" + new Gson().toJson(requestPack));
        }
        String methodName = ServiceCode.indexOf(".") > 0 ? ServiceCode.split("\\.")[1] : ServiceCode;
        Class<? extends Object> objClazz = service.getClass();

        try {
            Method method = objClazz.getMethod(methodName, String.class, WSIRequestPack.class);
            Observable<WSIResultPack> observable = (Observable<WSIResultPack>) method.invoke(service, AuthKey, requestPack);
            observable.compose(RxSchedulersHelper.<WSIResultPack>rxSchedulerHelper()).
                    subscribe(new CallSubscriber( new TypeToken<String>(){}.getType(), callback));
        } catch (Exception e) {
            e.printStackTrace();
            callback.onFailure( -1,-2, e.getMessage());
        }

    }


    @Override
    protected Interceptor getInterceptor() {
        return new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                Request original = chain.request();
                Request.Builder requestBuilder = original.newBuilder();
                requestBuilder.header("Content-Type", "application/json; charset=utf-8");
                requestBuilder.method(original.method(), original.body());
                Request request = requestBuilder.build();
                return chain.proceed(request);
            }
        };
    }

    public synchronized <T> T getService(Class<T> serviceClazz) {
        return createService(serviceClazz, APIWEBSERVICE.REMOTE_MCSWSIAPI, GsonConverterFactory.create());
    }
}
